package com.youboy.wechatapi.utils.http;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;
import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
import java.util.Map;

import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManager;

import org.apache.commons.io.IOUtils;
import org.codehaus.jackson.JsonParseException;
import org.codehaus.jackson.map.JsonMappingException;

import net.sf.json.JSONObject;

import com.youboy.wechatapi.utils.json.JacksonMapper;
import com.youboy.wechatapi.utils.wechat.MyX509TrustManager;

/**
 * @ProjectName：wechatapi
 * @author：冉尧（Yvan）
 * @CreateTime：2014年9月29日 上午10:18:28
 * @Remarks：
 */
public class HttpClient {
	
	public enum RequestMethod {
		GET, HEAD, POST, PUT, DELETE, OPTIONS, TRACE

	}
	
	public static String httpsRequest(String requestUrl)  {
		return httpsRequest(requestUrl, RequestMethod.POST, null);
	}
	
	public static String httpsRequest(String requestUrl, RequestMethod method)  {
		return httpsRequest(requestUrl, method, null);
	}
	
	public static String httpsRequest(String requestUrl, String outputStr)  {
		return httpsRequest(requestUrl, RequestMethod.POST, outputStr);
	}

	/**
	 * 发起https请求并获取结果
	 * 
	 * @param requestUrl 请求地址
	 * @param requestMethod 请求方式（GET、POST）
	 * @param outputStr  提交的数据
	 * @return String
	 * @throws IOException
	 * @throws NoSuchProviderException
	 * @throws NoSuchAlgorithmException
	 * @throws KeyManagementException
	 */
	public static String httpsRequest(String requestUrl, RequestMethod method, String outputStr) {
		
		StringBuffer buffer = new StringBuffer();

		// 创建SSLContext对象，并使用我们指定的信任管理器初始化
		TrustManager[] tm = { new MyX509TrustManager() };
		SSLContext sslContext;
		try {
			sslContext = SSLContext.getInstance("SSL", "SunJSSE");
			sslContext.init(null, tm, new java.security.SecureRandom());
			// 从上述SSLContext对象中得到SSLSocketFactory对象
			SSLSocketFactory ssf = sslContext.getSocketFactory();

			URL url = new URL(requestUrl);
			HttpsURLConnection httpUrlConn = (HttpsURLConnection) url.openConnection();
			httpUrlConn.setSSLSocketFactory(ssf);
			httpUrlConn.setDoOutput(true);
			httpUrlConn.setDoInput(true);
			httpUrlConn.setUseCaches(false);
			httpUrlConn.setRequestProperty("Content-type","text/html");//application/x-java-serialized-object
			// 设置请求方式（GET/POST）
			httpUrlConn.setRequestMethod(method.toString());

			if ("GET".equalsIgnoreCase(method.toString())){
				httpUrlConn.connect();
			}

			// 当有数据需要提交时
			if (null != outputStr) {
				OutputStream outputStream = httpUrlConn.getOutputStream();
				outputStream.write(outputStr.getBytes("UTF-8"));
				outputStream.flush();
				outputStream.close();
				int code = httpUrlConn.getResponseCode();
				System.out.println("code   " + code);
			}

			// 将返回的输入流转换成字符串
			InputStream inputStream = httpUrlConn.getInputStream();
			InputStreamReader inputStreamReader = new InputStreamReader(inputStream, "utf-8");
			BufferedReader bufferedReader = new BufferedReader(inputStreamReader);

			String str = null;
			while ((str = bufferedReader.readLine()) != null) {
				buffer.append(str);
			}
			bufferedReader.close();
			inputStreamReader.close();
			// 释放资源
			inputStream.close();
			inputStream = null;
			httpUrlConn.disconnect();
		} catch (NoSuchAlgorithmException e) {
			e.printStackTrace();
		} catch (NoSuchProviderException e) {
			e.printStackTrace();
		} catch (KeyManagementException e) {
			e.printStackTrace();
		} catch (MalformedURLException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
		
		return buffer.toString();
	}
	
	public static JSONObject getJsonObject(String requestUrl, String outputStr){
		JSONObject jsonObject = JSONObject.fromObject(httpsRequest(requestUrl, outputStr));
		return jsonObject;
	}
	
	@SuppressWarnings("unchecked")
	public static Map<String, Object> getMap(String requestUrl, String outputStr){
		String json = httpsRequest(requestUrl, outputStr);
		Map<String, Object> readValue = null;
		try {
			readValue = JacksonMapper.getInstance().readValue(json, Map.class);
		} catch (JsonParseException e) {
			e.printStackTrace();
		} catch (JsonMappingException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
		return readValue;
	}
	
	
	public  static String httpRequest(String apiurl,String parament) throws IOException {

		//parament = URLEncoder.encode(parament, "utf-8");
        // Configure and open a connection to the site you will send the request
        URL url = new URL(apiurl);
        URLConnection urlConnection = url.openConnection();
        // 设置doOutput属性为true表示将使用此urlConnection写入数据
        urlConnection.setDoOutput(true);
        // 定义待写入数据的内容类型，我们设置为application/x-www-form-urlencoded类型
        urlConnection.setRequestProperty("content-type", "text/html");//text/xml  application/x-www-form-urlencoded
        // 得到请求的输出流对象
        OutputStreamWriter out = new OutputStreamWriter(urlConnection.getOutputStream());
        out.write(parament);
        out.flush();
        out.close();

        // 从服务器读取响应
        InputStream inputStream = urlConnection.getInputStream();
        String encoding = urlConnection.getContentEncoding();

        String body = IOUtils.toString(inputStream, encoding);
        return body;

	}
}
